package timber.demo {

	/**
	Constructs a layout of buttons based upon a supplied XML object/string. Built to allow for a quick set of buttons for demo purposes.

	@author Matthew Richmond <matthew@choppingblock.com>
	@version 0.2
	@history 2008-10-07
	
	@Copyright 2008 Matthew Richmond <matthew@choppingblock.com>
    * 
	* This file is part of Timber.
    * 
	* Timber is free software: you can redistribute it and/or modify
	* it under the terms of the GNU Lesser General Public License as published by
	* the Free Software Foundation, either version 3 of the License, or
	* (at your option) any later version.
    * 
	* Timber is distributed in the hope that it will be useful,
	* but WITHOUT ANY WARRANTY; without even the implied warranty of
	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	* GNU Lesser General Public License for more details.
    * 
	* You should have received a copy of the GNU Lesser General Public License
	* along with Timber.  If not, see <http://www.gnu.org/licenses/>.

	@usage
	Activate with:
		<code>

			private function createDemoControls ():void{
				trace("createDemoControls");

				var d:XML = new XML();
				d = <ui>
					<buttons title="List Controls">
						<button title="Add" handler="addHandler" args="" />
						<button title="Remove 3" handler="removeHandler" args="3" />
					</buttons>
				</ui>

				var controls:DemoControls = new DemoControls(this, d)
				addChild(controls);
				
			};
	
			public function soundLoadStoreHandler (event:Event):void{
				trace("SoundControllerDemo: soundLoadStoreHandler");
	
				var args:Array =  DemoControls.parseStringArray(event.target.args, ["String", "Number", "Number", "Boolean"]);
				//trace("args is: "+args);
				_curSoundID = SoundController.getInstance().load.apply(this, args);

			};
	
		</code>

	*/

	import flash.display.*;
	import flash.events.*;
	import flash.utils.*;
	import timber.collection.*;
	import flash.text.*;

	public class DemoControls extends Sprite {

		public static var ALLOW_DISABLED:Boolean = false;
		private var _classRef:Object;
		private var _data:Iterator;
		private var _setCount:int = 0;
		private var _enabled:Boolean;
		private var _buttonArray:Array = new Array();
		
		// ------------------------------------
		// CONSTRUCTOR
		// ------------------------------------

		public function DemoControls ( classRef:Object, xml:XML ) {
			//trace("DemoControls");
			
			_classRef = classRef;
			
			var dlist:XMLList = xml.buttons;
			_data = new Iterator(dlist);
			
			create ();
		};

		// ------------------------------------
		// ACCESSORS
		// ------------------------------------

		public function set enabled( arg:Boolean ):void {
			if (ALLOW_DISABLED){
			
				if ( arg ){
					enable();
				} else {
					disable();
				};
			};
		};

		// ------------------------------------
		// INIT METHODS
		// ------------------------------------

		// ------------------------------------
		// CREATE / DESTROY
		// ------------------------------------
		
			public function create ():void{
				//trace("DemoControls: create");

				// build the button UI
				var obj:Object
				while ( (obj = _data.next() ) !== null ) {
					createButtonSet(obj);
					_setCount++
				}

			};

			public function createButtonSet (value:Object):void{
				//trace("DemoControls: createButtonSet for "+value);

				//Sprite to hold each set
				var sprite:Sprite = new Sprite();
				sprite.x = 0;
				sprite.y = _setCount * 60;
				
				var setTitle:TextField = createSetTitle( value.@title+":" );
				sprite.addChild(setTitle);

				var count:Number = value.button.length();

				for ( var i=0; i<count; i++ ) {
					//trace("value.button[i].@title is: "+value.button[i].@title);
					var b:DemoButton = new DemoButton();
					b.width = 75;
					b.label = value.button[i].@title;
					b.x = ( (b.width + 5) * i);
					b.y = 23;
					b.args = value.button[i].@args

					//trace("_classRef is: "+_classRef);
					try {
						// Code here might generate an exception
						b.addEventListener( MouseEvent.CLICK, toFunction (value.button[i].@handler) );

					} catch (error:Error) {
						// Code here deals with the problem
						trace("\r------------------------------------");
						//trace("\t"+error);
						trace("\tDemoControls cant find the handler method for '"+value.button[i].@title+"', make sure it exists within the "+_classRef+" class and make sure it's not private.");
						trace("------------------------------------\r");	
					}

					_buttonArray.push(b);
					if (ALLOW_DISABLED) b.enabled = false;
					sprite.addChild(b);
				};

				addChild(sprite);
			};

			public static function createSetTitle (value:String):TextField{
				//trace("DemoControls: createSetTitle");
				
				//Title
				var f:TextFormat = new TextFormat()
				f.font = "Arial Black";
				f.size = 14

				var field:TextField = new TextField()
				field.autoSize = TextFieldAutoSize.LEFT;
				field.selectable = false;
				field.text = value;
				field.setTextFormat(f);
			
				return field;
			};

			private function toFunction (value:String):Function{
				//trace("DemoControls: toFunction");

				return _classRef[value] as Function;
			};
		
		// ------------------------------------
		// METHODS
		// ------------------------------------
		
		public static function parseStringArray (str:String, dataType:Array):Array{
			//trace("DemoControls: parseStringArray for "+str);
			
			var a:Array = new Array();
			var ta:Array = str.split(",");
			for ( var i=0; i<ta.length; i++ ) {

				switch ( dataType[i].toLowerCase() ) {
					case "boolean":
					
						switch ( ta[i].toLowerCase() ) {
							case "true" : 
								a[i] = true;
								break;
							default:
								a[i] = false;
								break;
						};

						break;
					case "number":
					case "num": 
						a[i] = Number(ta[i]);
						break;
					case "class": 
						//var ClassReference:Class = getDefinitionByName(msgArray[i].args) as Class;
						var ClassReference:Class = getDefinitionByName(ta[i]) as Class;
						break;
					default:
						a[i] = ta[i];
						break;
				};
			};
			
			return a;
		};
		
		private function enable ():void{
			//trace("DemoControls: enable");
			
			var count:int = _buttonArray.length;
			for ( var i:int=0; i<count; i++ ) {
				var b:DemoButton = _buttonArray[i];
				b.enabled = true;
			};
			_enabled = true;
		};
		
		private function disable ():void{
			//trace("DemoControls: disable");
			
			var count:int = _buttonArray.length;
			for ( var i:int=0; i<count; i++ ) {
				var b:DemoButton = _buttonArray[i];
				b.enabled = false;
			};
			_enabled = false;
		};
		
		// ------------------------------------
		// EVENT METHODS
		// ------------------------------------
	};
};